<template>
    <div>
      <h1>ref</h1>
      <ul>
        <li ref="liOneRef">这是第一个li元素</li>
      </ul>
      <child-com ref="childRef"></child-com>
      <button @click="childAaa11">获取子组件的数据</button>
      <ul>
        <li ref="getList" v-for="index in 10" :key="index">
          这是第{{ index }}li
        </li>
      </ul>
    </div>
  </template>
  
  <script lang="ts">
  import { defineComponent,ref } from "vue";
  import ChildCom from "./components/ChildCom.vue";
  /* 
  ref在vue3当中获取元素 或者子组件标签 完成子向父的传值
  
  
  1.ref获取DOM元素
  ①在想获取的DOM元素上加上ref属性，并且自己起个名字（名字不要重复）
  ②在setup当中声明一个同样名字的变量，并且将与DOM上相同名字的变量，在setup的return当中返回
  ③ref声明的变量当中就是DOM元素
  
  
  函数调用时再ts当中，如果函数定义了数据类型，调用时需要指定数据类型
  */
  
  export default defineComponent({
    components: { ChildCom },
    setup() {
      // undefined  null  还有一种就可能是DOM,DOM元素的数据类型就是HTMLElement
      const liOneRef = ref<HTMLElement | null>();
      // console.log(liOneRef);
  
      // ref获取子组件 进行子向父的传值  在ts当中没有指定类型  组件如何指定数据类型
      // 指定组件的数据类型  <InstanceType<typeof ChildCom>>
      const childRef = ref<InstanceType<typeof ChildCom>>();
      // console.log(childRef);
      // console.log(childRef.value.childAaa);
  
      // 获取ref标记的子组件的数据时都需要在函数当中获取，获取数据时不能在setup当中调用函数，需要在浏览器中操作
      const childAaa11 = () => {
        console.log(childRef.value?.childAaa);
        console.log(childRef.value?.aa);
      };
  
      // childAaa11();
      // 在setup当中触发函数和在浏览器界面中触发函数不一样，因为setup在生命周期钩子的最前面触发
      // 获取v-for循环的多个refDOM节点
  
      // 空数组的数据类型  li节点10
      const getDOM: HTMLElement[] = [];
      const getList = (el: HTMLElement) => {
        getDOM.push(el);
      };
      console.log(getDOM);
      return {
        liOneRef,
        childRef,
        childAaa11,
        getList,
      };
    },
    mounted() {
      // console.log(this.$refs.liOneRef);
    },
  });
  </script>
  
  <style scoped>
  </style>